package com.md.api.common.utils;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Locale;
import java.util.Random;

/**
 * <pre>
 * 类说明:
 * </pre>
 * @author Chadwick
 * @mail hch_work@163.com
 * @version 
 * 创建时间：2016年4月15日 下午3:40:28
 */
public class NumberUtils {

	private static final DecimalFormat decimalFormatOne = new DecimalFormat("0.#######");//格式化设置最多保留两位小数
	/**
	 * 金额格式化
	 * @param s 金额
	 * @param len 小数位数
	 * @return 格式后的金额
	 */
	public static String insertComma(String s, int len) {
	    if (s == null || s.length() < 1) {
	        return "";
	    }
	    NumberFormat formater = null;
	    double num = Double.parseDouble(s);
	    if (len == 0) {
	        formater = new DecimalFormat("###,###");
	 
	    } else {
	        StringBuffer buff = new StringBuffer();
	        buff.append("###,###.");
	        for (int i = 0; i < len; i++) {
	            buff.append("#");
	        }
	        formater = new DecimalFormat(buff.toString());
	    }
	    return formater.format(num);
	}
	
	/**
	 * 金额去掉“,”
	 * @param s 金额
	 * @return 去掉“,”后的金额
	 */
	public static String delComma(String s) {
	    String formatString = "";
	    if (s != null && s.length() >= 1) {
	        formatString = s.replaceAll(",", "");
	    }
	 
	    return formatString;
	}
	
	/**
	   * 将给定的数字按给定的形式输出
	   * @param d double
	   * @param pattern String
	   *       #:表示有数字则输出数字，没有则空，如果输出位数多于＃的位数，
	   *          则超长输入
	   *       0:有数字则输出数字，没有补0
	   *          对于小数，有几个＃或0，就保留几位的小数；
	   *       例如： "###.00" -->表示输出的数值保留两位小数，不足两位的
	   *                          补0，多于两位的四舍五入
	   *              "###.0#" -->表示输出的数值可以保留一位或两位小数；
	   *                               整数显示为有一位小数，一位或两位小数
	   *                               的按原样显示，多于两位的四舍五入；
	   *              "###" --->表示为整数，小数部分四舍五入
	   *              ".###" -->12.234显示为.234
	   *              "#,###.0#" -->表示整数每隔3位加一个"，";
	   * @param l Locale
	   * @return String
	   */
	public static String formatNumber(double d,String pattern,Locale l){
	    String s = "";
	    try{
	      DecimalFormat nf = (DecimalFormat) NumberFormat.getInstance(l);
	      nf.applyPattern(pattern);
	      s = nf.format(d);
	    }catch(Exception e){
	      e.printStackTrace();
//	      Debug.println(" formatNumber is error!");
	    }
	    return s;
	}
	/**
	   * 按缺省的区域输出数字形式
	   * @param d double
	   * @param pattern String
	   * @return String
	   */
	public static String formatNumber(double d,String pattern){
	    return formatNumber(d,pattern, Locale.getDefault());
	}
	/**
	   * 格式化货币
	   * @param d double
	   * @param pattern String
	   *        "\u00A4#,###.00" :显示为 ￥1，234，234.10
	   * @param l Locale
	   * @return String
	   */
	public static String formatCurrency(double d,String pattern,Locale l){
	    String s = "";
	    try{
	      DecimalFormat nf = (DecimalFormat) NumberFormat.getCurrencyInstance(l);
	      nf.applyPattern(pattern);
	      s = nf.format(d);
	    }catch(Exception e){
	      e.printStackTrace();
//	      Debug.println(" formatNumber is error!");
	    }
	    return s;
	}
	/**
	   * 使用默认区域的指定方式显示货币
	   * @param d double
	   * @param pattern String
	   * @return String
	   */
	public static String formatCurrency(double d,String pattern){
	    return formatCurrency(d,pattern,Locale.getDefault());
	}
	/**
	   * 使用默认方式显示货币：
	   *     例如:￥12,345.46 默认保留2位小数，四舍五入
	   * @param d double
	   * @return String
	   */
	public static String formatCurrency(double d){
	    String s = "";
	   try{
	     DecimalFormat nf = (DecimalFormat) NumberFormat.getCurrencyInstance();
	     s = nf.format(d);
	   }catch(Exception e){
	     e.printStackTrace();
//	     Debug.println(" formatNumber is error!");
	   }
	   return s;
	}
	/**
	   * 按指定区域格式化百分数
	   * @param d
	   * @param pattern :"##,##.000%"-->不要忘记“%”
	   * @param l
	   * @return
	   */
	public static String formatPercent(double d,String pattern,Locale l){
	    String s = "";
	    try{
	      DecimalFormat df = (DecimalFormat)NumberFormat.getPercentInstance(l);
	      df.applyPattern(pattern);
	      s = df.format(d);
	    }catch(Exception e){
//	      Debug.print(e,"formatPercent is error!");
	    }
	    return s;
	}
	/**
	   * 使用默认区域格式化百分数
	   * @param d
	   * @param pattern
	   * @return
	   */
	public static String formatPercent(double d,String pattern){
	   return formatPercent(d,pattern,Locale.getDefault());
	}
	/**
	* 格式化百分数
	* @param d
	* @return
	*/
	public static String formatPercent(double d){
	   String s = "";
	   try{
	     DecimalFormat df = (DecimalFormat)NumberFormat.getPercentInstance();
	     s = df.format(d);
	   }catch(Exception e){
//	     Debug.print(e,"formatPercent is error!");
	   }
	   return s;
	}
	/**
	   * 输出数字的格式,如:1,234,567.89
	   * @param bd BigDecimal 要格式华的数字
	   * @param format String 格式 "###,##0"
	   * @return String
	   */
	public static String numberFormat(BigDecimal bd, String format) {
	    if (bd == null || "0".equals(bd.toString())) {
	      return "";
	    }
	    DecimalFormat bf = new DecimalFormat(format);
	    return bf.format(bd);
	}



	public static Double getPercent(int x,int y){
		double baiy=x*1.0;
		double baiz=y*1.0;
		double fen=baiy/baiz;
		BigDecimal b = new BigDecimal(fen);
		fen = b.setScale(4, BigDecimal.ROUND_HALF_UP).doubleValue();
		return fen;
	}

	public static Double getPercentX100(int x,int y){
		double baiy=x*1.0;
		double baiz=y*1.0;
		double fen=baiy/baiz;
		BigDecimal b = new BigDecimal(fen * 100);
		fen = b.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
		return fen;
	}

	/**
	 * 生成指定长度的随机数
	 *
	 * @param randomNumLen
	 *            目标随机数的长度
	 * @return 随机数
	 */
	public static String generateRandomNumber(final int randomNumLen)
	{
		//随机种子数组
		int[] seedNum = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
		Random random = new Random();
		for (int i = 10; i > 1; i--)
		{
			//在数组中循环随机取数，然后交换，得到一个随机序列的数组
			int index = random.nextInt(i);
			int tempNum = seedNum[index];
			seedNum[index] = seedNum[i - 1];
			seedNum[i - 1] = tempNum;
		}

		////////////////////////////////////////////////////////////////////////////////
		int resultNum = 0;
		//0在首位的标识位
		boolean zeroAtHeader = false;
		StringBuffer numBuffer = new StringBuffer();

		// 遍历随机序列数组，取得指定长度的随机数
		for (int i = 0; i < randomNumLen; i++)
		{
			//随机数中，会出现0在首位的情况，如果用int型表示，会导致位数少一位
			if (seedNum[0] == 0)
			{
				zeroAtHeader = true;
			}
			resultNum = resultNum * 10 + seedNum[i];
		}
		if (zeroAtHeader)
		{
			numBuffer.append(0);
		}
		return numBuffer.append(resultNum).toString();
	}

	/**
	 * 提供精确的加法运算。
	 * @param v1 被加数
	 * @param v2 加数
	 * @return 两个参数的和
	 */
	public static double add(double v1,double v2){
		BigDecimal b1 = new BigDecimal(Double.toString(v1));
		BigDecimal b2 = new BigDecimal(Double.toString(v2));
		return b1.add(b2).doubleValue();
	}
	/**
	 * 提供精确的减法运算。
	 * @param v1 被减数
	 * @param v2 减数
	 * @return 两个参数的差
	 */
	public static double sub(double v1,double v2){
		BigDecimal b1 = new BigDecimal(Double.toString(v1));
		BigDecimal b2 = new BigDecimal(Double.toString(v2));
		return b1.subtract(b2).doubleValue();
	}
	/**
	 * 提供精确的乘法运算。
	 * @param v1 被乘数
	 * @param v2 乘数
	 * @return 两个参数的积
	 */
	public static double mul(double v1,double v2){
		BigDecimal b1 = new BigDecimal(Double.toString(v1));
		BigDecimal b2 = new BigDecimal(Double.toString(v2));
		return b1.multiply(b2).doubleValue();
	}

	public static int mul(float v1,int v2){
		BigDecimal b1 = new BigDecimal(Float.toString(v1));
		BigDecimal b2 = new BigDecimal(Integer.toString(v2));
		return b1.multiply(b2).intValue();
	}

	public static double mul(double v1,int v2){
		BigDecimal b1 = new BigDecimal(Double.toString(v1));
		BigDecimal b2 = new BigDecimal(Integer.toString(v2));
		return b1.multiply(b2).doubleValue();
	}

	/**
	 * 提供（相对）精确的除法运算，当发生除不尽的情况时，精确到
	 * 小数点以后10位，以后的数字四舍五入。
	 * @param v1 被除数
	 * @param v2 除数
	 * @return 两个参数的商
	 */
	public static double div(double v1,double v2){
		return div(v1, v2, 10);
	}

	/**
	 * 提供（相对）精确的除法运算。当发生除不尽的情况时，由scale参数指
	 * 定精度，以后的数字四舍五入。
	 * @param v1 被除数
	 * @param v2 除数
	 * @param scale 表示表示需要精确到小数点以后几位。
	 * @return 两个参数的商
	 */
	public static double div(double v1,double v2,int scale){
		if(scale<0){
			throw new IllegalArgumentException(
					"The scale must be a positive integer or zero");
		}
		BigDecimal b1 = new BigDecimal(Double.toString(v1));
		BigDecimal b2 = new BigDecimal(Double.toString(v2));
		return b1.divide(b2,scale,BigDecimal.ROUND_HALF_UP).doubleValue();
	}

	/**
	 * 提供精确的小数位四舍五入处理。
	 * @param v 需要四舍五入的数字
	 * @param scale 小数点后保留几位
	 * @return 四舍五入后的结果
	 */
	public static double round(double v,int scale){
		if(scale<0){
			throw new IllegalArgumentException(
					"The scale must be a positive integer or zero");
		}
		BigDecimal b = new BigDecimal(Double.toString(v));
		BigDecimal one = new BigDecimal("1");
		return b.divide(one,scale,BigDecimal.ROUND_HALF_UP).doubleValue();
	}

	/**
	 * 判断为存数字的方法
	 * @param str
	 * @return
	 */
	public static boolean isNumeric(String str) {
		for (int i = str.length(); --i >= 0;) {
			if (!Character.isDigit(str.charAt(i))) {
				return false;
			}
		}
		return true;
	}


	/**
	 * @param a
	 * @param b
	 * @param c 误差值
	 * @return
	 */
	//判断是否在误差以内
	public static boolean errorLimit(double a,double b,double c) {
		double d3= Math.abs(a-b);
		if(d3<=c){
			return true;
		}
		return false;
	}


	//对数字强转double类型  再进行格式转化  使其不使用科学计数法表示
	public static String numFormat (Object num){
		if (num==null){	//如果没有数据则直接返回空字符串
			return "";
		}else {
			String par = "0.##";
			String[] s = num.toString().split("\\.");
			if (s.length>1){
				String s1 = s[1];
				if (s1.length()>2){
					for(int i =2;i<s1.length();i++){
						par= par.concat("#");
					}
				}
			}
			DecimalFormat decimalFormat = new DecimalFormat(par);
			String strMoney = num.toString();	//因为存在多值需要先转化为字符串
			if(strMoney.contains(",")){	//多值
				StringBuilder sb = new StringBuilder();
				String[] split = strMoney.split(",");
				for (int i = 0; i < split.length; i++) {
					double money = Double.valueOf(split[i]);	//字符串数据转化为double
					sb.append(decimalFormat.format(money));		//拼接金额
					if (i<(split.length-1)){					//
						sb.append(",");
					}
				}
				return sb.toString();
			}else {	//唯一值	直接转化返回即可
				double money = Double.valueOf(strMoney);
				return decimalFormat.format(money);
			}
		}
	}

	/**
	 * 判断为存数字的方法
	 * @param par 保留位数
	 * @return
	 */
	public static String numFormat (Object num,int part){
		if (num==null){	//如果没有数据则直接返回空字符串
			return "";
		}else {
			String par = "0.#";
			if (part>1){
				for(int i =1;i<part-1;i++){
					par= par.concat("#");
				}
			}
			DecimalFormat decimalFormat = new DecimalFormat(par);
			String strMoney = num.toString();	//因为存在多值需要先转化为字符串
			if(strMoney.contains(",")){	//多值
				StringBuilder sb = new StringBuilder();
				String[] split = strMoney.split(",");
				for (int i = 0; i < split.length; i++) {
					double money = Double.valueOf(split[i]);	//字符串数据转化为double
					sb.append(decimalFormat.format(money));		//拼接金额
					if (i<(split.length-1)){					//
						sb.append(",");
					}
				}
				return sb.toString();
			}else {	//唯一值	直接转化返回即可
				double money = Double.valueOf(strMoney);
				return decimalFormat.format(money);
			}
		}
	}

	//对从solr中取出数字强转double类型  再进行格式转化  使其不使用科学计数法表示
	public static Double formatDouble(Object num){
		if (num==null){	//如果没有数据则直接返回空字符串
			return null;
		}
		return Double.parseDouble(decimalFormatOne.format(num));
	}

	public static void main(String[] args) {
	    String s = numFormat(7726.4737);
	    System.out.println(s);
	}
}